home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / MATRICES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-18  |  24.2 KB  |  1,244 lines

  1. /****************************************************************************
  2. *                matrices.c
  3. *
  4. *  This module contains code to manipulate 4x4 matrices.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other 
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If 
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "vector.h"
  26. #include "povproto.h"
  27. #include "matrices.h"
  28.  
  29.  
  30.  
  31. /*****************************************************************************
  32. * Local preprocessor defines
  33. ******************************************************************************/
  34.  
  35.  
  36.  
  37. /*****************************************************************************
  38. * Local typedefs
  39. ******************************************************************************/
  40.  
  41.  
  42.  
  43. /*****************************************************************************
  44. * Local variables
  45. ******************************************************************************/
  46.  
  47.  
  48.  
  49. /*****************************************************************************
  50. * Static functions
  51. ******************************************************************************/
  52.  
  53.  
  54.  
  55. /*****************************************************************************
  56. *
  57. * FUNCTION
  58. *
  59. * INPUT
  60. *   
  61. * OUTPUT
  62. *   
  63. * RETURNS
  64. *   
  65. * AUTHOR
  66. *
  67. *   POV-Ray Team
  68. *   
  69. * DESCRIPTION
  70. *
  71. *   Initialize the matrix to the following values:
  72. *
  73. *     0.0   0.0   0.0   0.0
  74. *     0.0   0.0   0.0   0.0
  75. *     0.0   0.0   0.0   0.0
  76. *     0.0   0.0   0.0   0.0
  77. *
  78. * CHANGES
  79. *
  80. *   -
  81. *
  82. ******************************************************************************/
  83.  
  84. void MZero (result)
  85. MATRIX result;
  86. {
  87.   register int i, j;
  88.  
  89.   for (i = 0 ; i < 4 ; i++)
  90.   {
  91.     for (j = 0 ; j < 4 ; j++)
  92.     {
  93.       result[i][j] = 0.0;
  94.     }
  95.   }
  96. }
  97.  
  98.  
  99.  
  100. /*****************************************************************************
  101. *
  102. * FUNCTION
  103. *
  104. * INPUT
  105. *   
  106. * OUTPUT
  107. *   
  108. * RETURNS
  109. *   
  110. * AUTHOR
  111. *
  112. *   POV-Ray Team
  113. *   
  114. * DESCRIPTION
  115. *
  116. *   Initialize the matrix to the following values:
  117. *
  118. *     1.0   0.0   0.0   0.0
  119. *     0.0   1.0   0.0   0.0
  120. *     0.0   0.0   1.0   0.0
  121. *     0.0   0.0   0.0   1.0
  122. *
  123. * CHANGES
  124. *
  125. *   -
  126. *
  127. ******************************************************************************/
  128.  
  129. void MIdentity (result)
  130. MATRIX result;
  131. {
  132.   register int i, j;
  133.  
  134.   for (i = 0 ; i < 4 ; i++)
  135.   {
  136.     for (j = 0 ; j < 4 ; j++)
  137.     {
  138.       if (i == j)
  139.       {
  140.         result[i][j] = 1.0;
  141.       }
  142.       else
  143.       {
  144.         result[i][j] = 0.0;
  145.       }
  146.     }
  147.   }
  148. }
  149.  
  150.  
  151.  
  152. /*****************************************************************************
  153. *
  154. * FUNCTION
  155. *
  156. * INPUT
  157. *   
  158. * OUTPUT
  159. *   
  160. * RETURNS
  161. *   
  162. * AUTHOR
  163. *
  164. *   POV-Ray Team
  165. *   
  166. * DESCRIPTION
  167. *
  168. *   -
  169. *
  170. * CHANGES
  171. *
  172. *   -
  173. *
  174. ******************************************************************************/
  175.  
  176. void MTimes (result, matrix1, matrix2)
  177. MATRIX result, matrix1, matrix2;
  178. {
  179.   register int i, j, k;
  180.   MATRIX temp_matrix;
  181.  
  182.   for (i = 0 ; i < 4 ; i++)
  183.   {
  184.     for (j = 0 ; j < 4 ; j++)
  185.     {
  186.       temp_matrix[i][j] = 0.0;
  187.  
  188.       for (k = 0 ; k < 4 ; k++)
  189.       {
  190.         temp_matrix[i][j] += matrix1[i][k] * matrix2[k][j];
  191.       }
  192.     }
  193.   }
  194.  
  195.   for (i = 0 ; i < 4 ; i++)
  196.   {
  197.     for (j = 0 ; j < 4 ; j++)
  198.     {
  199.       result[i][j] = temp_matrix[i][j];
  200.     }
  201.   }
  202. }
  203.  
  204.  
  205.  
  206. /*  AAC - These are not used, so they are commented out to save code space...
  207.  
  208. void MAdd (result, matrix1, matrix2)
  209. MATRIX result, *matrix1, *matrix2;
  210. {
  211.   register int i, j;
  212.  
  213.   for (i = 0 ; i < 4 ; i++)
  214.     for (j = 0 ; j < 4 ; j++)
  215.      result[i][j] = (*matrix1)[i][j] + (*matrix2)[i][j];
  216. }
  217.  
  218. void MSub (result, matrix1, matrix2)
  219. MATRIX result, matrix1, matrix2;
  220. {
  221.   register int i, j;
  222.  
  223.   for (i = 0 ; i < 4 ; i++)
  224.     for (j = 0 ; j < 4 ; j++)
  225.      result[i][j] = matrix1[i][j] - matrix2[i][j];
  226. }
  227.  
  228. void MScale (result, matrix1, amount)
  229. MATRIX result, matrix1;
  230. DBL amount;
  231. {
  232.   register int i, j;
  233.  
  234.   for (i = 0 ; i < 4 ; i++)
  235.     for (j = 0 ; j < 4 ; j++)
  236.       result[i][j] = matrix1[i][j] * amount;
  237. }
  238. ... up to here! */
  239.  
  240.  
  241.  
  242. /*****************************************************************************
  243. *
  244. * FUNCTION
  245. *
  246. * INPUT
  247. *   
  248. * OUTPUT
  249. *   
  250. * RETURNS
  251. *   
  252. * AUTHOR
  253. *
  254. *   POV-Ray Team
  255. *   
  256. * DESCRIPTION
  257. *
  258. *   -
  259. *
  260. * CHANGES
  261. *
  262. *   -
  263. *
  264. ******************************************************************************/
  265.  
  266. void MTranspose (result, matrix1)
  267. MATRIX result, matrix1;
  268. {
  269.   register int i, j;
  270.   MATRIX temp_matrix;
  271.  
  272.   for (i = 0 ; i < 4 ; i++)
  273.   {
  274.     for (j = 0 ; j < 4 ; j++)
  275.     {
  276.       temp_matrix[i][j] = matrix1[j][i];
  277.     }
  278.   }
  279.  
  280.   for (i = 0 ; i < 4 ; i++)
  281.   {
  282.     for (j = 0 ; j < 4 ; j++)
  283.     {
  284.       result[i][j] = temp_matrix[i][j];
  285.     }
  286.   }
  287. }
  288.  
  289.  
  290.  
  291. /*****************************************************************************
  292. *
  293. * FUNCTION
  294. *
  295. * INPUT
  296. *   
  297. * OUTPUT
  298. *
  299. * RETURNS
  300. *   
  301. * AUTHOR
  302. *
  303. *   POV-Ray Team
  304. *   
  305. * DESCRIPTION
  306. *
  307. *   -
  308. *
  309. * CHANGES
  310. *
  311. *   Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  312. *
  313. ******************************************************************************/
  314.  
  315. void MTransPoint (result, vector, transform)
  316. VECTOR result, vector;
  317. TRANSFORM *transform;
  318. {
  319.   register int i;
  320.   DBL answer_array[4];
  321.   MATRIX *matrix;
  322.  
  323.   matrix = (MATRIX *) transform->matrix;
  324.  
  325.   for (i = 0 ; i < 3 ; i++)
  326.   {
  327.     answer_array[i] = vector[X] * (*matrix)[0][i] +
  328.                       vector[Y] * (*matrix)[1][i] +
  329.                       vector[Z] * (*matrix)[2][i] + (*matrix)[3][i];
  330.   }
  331.  
  332.   result[X] = answer_array[0];
  333.   result[Y] = answer_array[1];
  334.   result[Z] = answer_array[2];
  335. }
  336.  
  337.  
  338.  
  339. /*****************************************************************************
  340. *
  341. * FUNCTION
  342. *
  343. * INPUT
  344. *   
  345. * OUTPUT
  346. *   
  347. * RETURNS
  348. *   
  349. * AUTHOR
  350. *
  351. *   POV-Ray Team
  352. *   
  353. * DESCRIPTION
  354. *
  355. *   -
  356. *
  357. * CHANGES
  358. *
  359. *   Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  360. *
  361. ******************************************************************************/
  362.  
  363. void MInvTransPoint (result, vector, transform)
  364. VECTOR result, vector;
  365. TRANSFORM *transform;
  366. {
  367.   register int i;
  368.   DBL answer_array[4];
  369.   MATRIX *matrix;
  370.  
  371.   matrix = (MATRIX *) transform->inverse;
  372.  
  373.   for (i = 0 ; i < 3 ; i++)
  374.   {
  375.     answer_array[i] = vector[X] * (*matrix)[0][i] +
  376.                       vector[Y] * (*matrix)[1][i] +
  377.                       vector[Z] * (*matrix)[2][i] + (*matrix)[3][i];
  378.   }
  379.  
  380.   result[X] = answer_array[0];
  381.   result[Y] = answer_array[1];
  382.   result[Z] = answer_array[2];
  383. }
  384.  
  385.  
  386.  
  387. /*****************************************************************************
  388. *
  389. * FUNCTION
  390. *
  391. * INPUT
  392. *   
  393. * OUTPUT
  394. *   
  395. * RETURNS
  396. *   
  397. * AUTHOR
  398. *
  399. *   POV-Ray Team
  400. *   
  401. * DESCRIPTION
  402. *
  403. *   -
  404. *
  405. * CHANGES
  406. *
  407. *   Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  408. *
  409. ******************************************************************************/
  410.  
  411. void MTransDirection (result, vector, transform)
  412. VECTOR result, vector;
  413. TRANSFORM *transform;
  414. {
  415.   register int i;
  416.   DBL answer_array[4];
  417.   MATRIX *matrix;
  418.  
  419.   matrix = (MATRIX *) transform->matrix;
  420.  
  421.   for (i = 0 ; i < 3 ; i++)
  422.   {
  423.     answer_array[i] = vector[X] * (*matrix)[0][i] +
  424.                       vector[Y] * (*matrix)[1][i] +
  425.                       vector[Z] * (*matrix)[2][i];
  426.   }
  427.  
  428.   result[X] = answer_array[0];
  429.   result[Y] = answer_array[1];
  430.   result[Z] = answer_array[2];
  431. }
  432.  
  433.  
  434.  
  435. /*****************************************************************************
  436. *
  437. * FUNCTION
  438. *
  439. * INPUT
  440. *   
  441. * OUTPUT
  442. *   
  443. * RETURNS
  444. *   
  445. * AUTHOR
  446. *
  447. *   POV-Ray Team
  448. *   
  449. * DESCRIPTION
  450. *
  451. *   -
  452. *
  453. * CHANGES
  454. *
  455. *   Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  456. *
  457. ******************************************************************************/
  458.  
  459. void MInvTransDirection (result, vector, transform)
  460. VECTOR result, vector;
  461. TRANSFORM *transform;
  462. {
  463.   register int i;
  464.   DBL answer_array[4];
  465.   MATRIX *matrix;
  466.  
  467.   matrix = (MATRIX *) transform->inverse;
  468.  
  469.   for (i = 0 ; i < 3 ; i++)
  470.   {
  471.     answer_array[i] = vector[X] * (*matrix)[0][i] +
  472.                       vector[Y] * (*matrix)[1][i] +
  473.                       vector[Z] * (*matrix)[2][i];
  474.   }
  475.  
  476.   result[X] = answer_array[0];
  477.   result[Y] = answer_array[1];
  478.   result[Z] = answer_array[2];
  479. }
  480.  
  481.  
  482.  
  483. /*****************************************************************************
  484. *
  485. * FUNCTION
  486. *
  487. * INPUT
  488. *   
  489. * OUTPUT
  490. *   
  491. * RETURNS
  492. *   
  493. * AUTHOR
  494. *
  495. *   POV-Ray Team
  496. *   
  497. * DESCRIPTION
  498. *
  499. *   -
  500. *
  501. * CHANGES
  502. *
  503. *   -
  504. *
  505. ******************************************************************************/
  506.  
  507. void MTransNormal (result, vector, transform)
  508. VECTOR result, vector;
  509. TRANSFORM *transform;
  510. {
  511.   register int i;
  512.   DBL answer_array[3];
  513.   MATRIX *matrix;
  514.  
  515.   matrix = (MATRIX *) transform->inverse;
  516.  
  517.   for (i = 0 ; i < 3 ; i++)
  518.   {
  519.     answer_array[i] = vector[X] * (*matrix)[i][0] +
  520.                       vector[Y] * (*matrix)[i][1] +
  521.                       vector[Z] * (*matrix)[i][2];
  522.   }
  523.  
  524.   result[X] = answer_array[0];
  525.   result[Y] = answer_array[1];
  526.   result[Z] = answer_array[2];
  527. }
  528.  
  529.  
  530.  
  531. /*****************************************************************************
  532. *
  533. * FUNCTION
  534. *
  535. * INPUT
  536. *   
  537. * OUTPUT
  538. *   
  539. * RETURNS
  540. *   
  541. * AUTHOR
  542. *
  543. *   POV-Ray Team
  544. *   
  545. * DESCRIPTION
  546. *
  547. *   -
  548. *
  549. * CHANGES
  550. *
  551. *   -
  552. *
  553. ******************************************************************************/
  554.  
  555. void MInvTransNormal (result, vector, transform)
  556. VECTOR result, vector;
  557. TRANSFORM *transform;
  558. {
  559.   register int i;
  560.   DBL answer_array[3];
  561.   MATRIX *matrix;
  562.  
  563.   matrix = (MATRIX *) transform->matrix;
  564.  
  565.   for (i = 0 ; i < 3 ; i++)
  566.   {
  567.     answer_array[i] = vector[X] * (*matrix)[i][0] +
  568.                       vector[Y] * (*matrix)[i][1] +
  569.                       vector[Z] * (*matrix)[i][2];
  570.   }
  571.  
  572.   result[X] = answer_array[0];
  573.   result[Y] = answer_array[1];
  574.   result[Z] = answer_array[2];
  575. }
  576.  
  577.  
  578.  
  579. /*****************************************************************************
  580. *
  581. * FUNCTION
  582. *
  583. * INPUT
  584. *   
  585. * OUTPUT
  586. *   
  587. * RETURNS
  588. *   
  589. * AUTHOR
  590. *
  591. *   POV-Ray Team
  592. *   
  593. * DESCRIPTION
  594. *
  595. *   -
  596. *
  597. * CHANGES
  598. *
  599. *   -
  600. *
  601. ******************************************************************************/
  602.  
  603. void Compute_Scaling_Transform (result, vector)
  604. TRANSFORM *result;
  605. VECTOR vector;
  606. {
  607.   MIdentity (result->matrix);
  608.  
  609.   (result->matrix)[0][0] = vector[X];
  610.   (result->matrix)[1][1] = vector[Y];
  611.   (result->matrix)[2][2] = vector[Z];
  612.  
  613.   MIdentity (result->inverse);
  614.  
  615.   (result->inverse)[0][0] = 1.0 / vector[X];
  616.   (result->inverse)[1][1] = 1.0 / vector[Y];
  617.   (result->inverse)[2][2] = 1.0 / vector[Z];
  618. }
  619.  
  620.  
  621.  
  622. /*****************************************************************************
  623. *
  624. * FUNCTION
  625. *
  626. *   Compute_Matrix_Transform
  627. *
  628. * INPUT
  629. *
  630. *   matrix - matrix from which to create transform
  631. *
  632. * OUTPUT
  633. *
  634. *   result - complete transform
  635. *
  636. * RETURNS
  637. *
  638. * AUTHOR
  639. *
  640. *   POV-Ray Team
  641. *
  642. * DESCRIPTION
  643. *
  644. *   Builds a complete transform from a matrix.
  645. *
  646. * CHANGES
  647. *
  648. *   June 1995 : Creation
  649. *
  650. ******************************************************************************/
  651.  
  652. void Compute_Matrix_Transform (result, matrix)
  653. TRANSFORM *result;
  654. MATRIX matrix;
  655. {
  656.   register int i;
  657.  
  658.   for (i = 0; i < 4; i++)
  659.   {
  660.     (result->matrix)[i][0] = matrix[i][0];
  661.     (result->matrix)[i][1] = matrix[i][1];
  662.     (result->matrix)[i][2] = matrix[i][2];
  663.     (result->matrix)[i][3] = matrix[i][3];
  664.   }
  665.  
  666.   MInvers(result->inverse, result->matrix);
  667. }
  668.  
  669.  
  670.  
  671. /* AAC - This is not used, so it's commented out...
  672.  
  673. void Compute_Inversion_Transform (result)
  674. TRANSFORM *result;
  675. {
  676.   MIdentity (result->matrix);
  677.  
  678.   (result->matrix)[0][0] = -1.0;
  679.   (result->matrix)[1][1] = -1.0;
  680.   (result->matrix)[2][2] = -1.0;
  681.   (result->matrix)[3][3] = -1.0;
  682.  
  683.  
  684.   (result->inverse)[0][0] = -1.0;
  685.   (result->inverse)[1][1] = -1.0;
  686.   (result->inverse)[2][2] = -1.0;
  687.   (result->inverse)[3][3] = -1.0;
  688. }
  689. ... up to here! */
  690.  
  691.  
  692.  
  693. /*****************************************************************************
  694. *
  695. * FUNCTION
  696. *
  697. * INPUT
  698. *   
  699. * OUTPUT
  700. *   
  701. * RETURNS
  702. *   
  703. * AUTHOR
  704. *
  705. *   POV-Ray Team
  706. *   
  707. * DESCRIPTION
  708. *
  709. *   -
  710. *
  711. * CHANGES
  712. *
  713. *   -
  714. *
  715. ******************************************************************************/
  716.  
  717. void Compute_Translation_Transform (transform, vector)
  718. TRANSFORM *transform;
  719. VECTOR vector;
  720. {
  721.   MIdentity (transform->matrix);
  722.  
  723.   (transform->matrix)[3][0] = vector[X];
  724.   (transform->matrix)[3][1] = vector[Y];
  725.   (transform->matrix)[3][2] = vector[Z];
  726.  
  727.   MIdentity (transform->inverse);
  728.  
  729.   (transform->inverse)[3][0] = -vector[X];
  730.   (transform->inverse)[3][1] = -vector[Y];
  731.   (transform->inverse)[3][2] = -vector[Z];
  732. }
  733.  
  734.  
  735.  
  736. /*****************************************************************************
  737. *
  738. * FUNCTION
  739. *
  740. * INPUT
  741. *   
  742. * OUTPUT
  743. *   
  744. * RETURNS
  745. *   
  746. * AUTHOR
  747. *
  748. *   POV-Ray Team
  749. *   
  750. * DESCRIPTION
  751. *
  752. *   -
  753. *
  754. * CHANGES
  755. *
  756. *   -
  757. *
  758. ******************************************************************************/
  759.  
  760. void Compute_Rotation_Transform (transform, vector)
  761. TRANSFORM *transform;
  762. VECTOR vector;
  763. {
  764.   register DBL cosx, cosy, cosz, sinx, siny, sinz;
  765.   MATRIX Matrix;
  766.   VECTOR Radian_Vector;
  767.  
  768.   VScale (Radian_Vector, vector, M_PI/180.0);
  769.  
  770.   MIdentity (transform->matrix);
  771.  
  772.   cosx = cos (Radian_Vector[X]);
  773.   sinx = sin (Radian_Vector[X]);
  774.   cosy = cos (Radian_Vector[Y]);
  775.   siny = sin (Radian_Vector[Y]);
  776.   cosz = cos (Radian_Vector[Z]);
  777.   sinz = sin (Radian_Vector[Z]);
  778.  
  779.   (transform->matrix) [1][1] = cosx;
  780.   (transform->matrix) [2][2] = cosx;
  781.   (transform->matrix) [1][2] = sinx;
  782.   (transform->matrix) [2][1] = 0.0 - sinx;
  783.  
  784.   MTranspose (transform->inverse, transform->matrix);
  785.  
  786.   MIdentity (Matrix);
  787.  
  788.   Matrix [0][0] = cosy;
  789.   Matrix [2][2] = cosy;
  790.   Matrix [0][2] = 0.0 - siny;
  791.   Matrix [2][0] = siny;
  792.  
  793.   MTimes (transform->matrix, transform->matrix, Matrix);
  794.  
  795.   MTranspose (Matrix, Matrix);
  796.  
  797.   MTimes (transform->inverse, Matrix, transform->inverse);
  798.  
  799.   MIdentity (Matrix);
  800.  
  801.   Matrix [0][0] = cosz;
  802.   Matrix [1][1] = cosz;
  803.   Matrix [0][1] = sinz;
  804.   Matrix [1][0] = 0.0 - sinz;
  805.  
  806.   MTimes (transform->matrix, transform->matrix, Matrix);
  807.  
  808.   MTranspose (Matrix, Matrix);
  809.  
  810.   MTimes (transform->inverse, Matrix, transform->inverse);
  811. }
  812.  
  813.  
  814.  
  815. /* AAC - This is not used so it's commented out...
  816.  
  817. void Compute_Look_At_Transform (result, Look_At, Up, Right)
  818. TRANSFORM *result;
  819. VECTOR Look_At, Up, Right;
  820. {
  821.   MIdentity (result->inverse);
  822.  
  823.   (result->matrix)[0][0] = Right[X];
  824.   (result->matrix)[0][1] = Right[Y];
  825.   (result->matrix)[0][2] = Right[Z];
  826.  
  827.   (result->matrix)[1][0] = Up[X];
  828.   (result->matrix)[1][1] = Up[Y];
  829.   (result->matrix)[1][2] = Up[Z];
  830.  
  831.   (result->matrix)[2][0] = Look_At[X];
  832.   (result->matrix)[2][1] = Look_At[Y];
  833.   (result->matrix)[2][2] = Look_At[Z];
  834.  
  835.   MIdentity (result->matrix);
  836.  
  837.   MTranspose (result->matrix, result->inverse);
  838. }
  839. ... up to here! */
  840.  
  841.  
  842.  
  843. /*****************************************************************************
  844. *
  845. * FUNCTION
  846. *
  847. * INPUT
  848. *   
  849. * OUTPUT
  850. *   
  851. * RETURNS
  852. *   
  853. * AUTHOR
  854. *
  855. *   POV-Ray Team
  856. *   
  857. * DESCRIPTION
  858. *
  859. *   -
  860. *
  861. * CHANGES
  862. *
  863. *   -
  864. *
  865. ******************************************************************************/
  866.  
  867. void Compose_Transforms (Original_Transform, New_Transform)
  868. TRANSFORM *Original_Transform, *New_Transform;
  869. {
  870.   MTimes(Original_Transform->matrix, Original_Transform->matrix,  New_Transform->matrix);
  871.  
  872.   MTimes(Original_Transform->inverse, New_Transform->inverse, Original_Transform->inverse);
  873. }
  874.  
  875.  
  876.  
  877. /*****************************************************************************
  878. *
  879. * FUNCTION
  880. *
  881. * INPUT
  882. *
  883. * OUTPUT
  884. *
  885. * RETURNS
  886. *   
  887. * AUTHOR
  888. *
  889. *   POV-Ray Team
  890. *   
  891. * DESCRIPTION
  892. *
  893. *   Rotation about an arbitrary axis - formula from:
  894. *
  895. *     "Computational Geometry for Design and Manufacture", Faux & Pratt
  896. *
  897. *   NOTE: The angles for this transform are specified in radians.
  898. *
  899. * CHANGES
  900. *
  901. *   -
  902. *
  903. ******************************************************************************/
  904.  
  905. void Compute_Axis_Rotation_Transform (transform, V1, angle)
  906. TRANSFORM *transform;
  907. VECTOR V1;
  908. DBL angle;
  909. {
  910.   DBL l, cosx, sinx;
  911.  
  912.   VLength(l, V1);
  913.   VInverseScaleEq(V1, l);
  914.  
  915.   MIdentity(transform->matrix);
  916.  
  917.   cosx = cos(angle);
  918.   sinx = sin(angle);
  919.  
  920.   transform->matrix[0][0] = V1[X] * V1[X] + cosx * (1.0 - V1[X] * V1[X]);
  921.   transform->matrix[0][1] = V1[X] * V1[Y] * (1.0 - cosx) + V1[Z] * sinx;
  922.   transform->matrix[0][2] = V1[X] * V1[Z] * (1.0 - cosx) - V1[Y] * sinx;
  923.  
  924.   transform->matrix[1][0] = V1[X] * V1[Y] * (1.0 - cosx) - V1[Z] * sinx;
  925.   transform->matrix[1][1] = V1[Y] * V1[Y] + cosx * (1.0 - V1[Y] * V1[Y]);
  926.   transform->matrix[1][2] = V1[Y] * V1[Z] * (1.0 - cosx) + V1[X] * sinx;
  927.  
  928.   transform->matrix[2][0] = V1[X] * V1[Z] * (1.0 - cosx) + V1[Y] * sinx;
  929.   transform->matrix[2][1] = V1[Y] * V1[Z] * (1.0 - cosx) - V1[X] * sinx;
  930.   transform->matrix[2][2] = V1[Z] * V1[Z] + cosx * (1.0 - V1[Z] * V1[Z]);
  931.  
  932.   MTranspose(transform->inverse, transform->matrix);
  933. }
  934.  
  935.  
  936.  
  937. /*****************************************************************************
  938. *
  939. * FUNCTION
  940. *
  941. * INPUT
  942. *   
  943. * OUTPUT
  944. *   
  945. * RETURNS
  946. *   
  947. * AUTHOR
  948. *
  949. *   POV-Ray Team
  950. *   
  951. * DESCRIPTION
  952. *
  953. *   Given a point and a direction and a radius, find the transform
  954. *   that brings these into a canonical coordinate system
  955. *
  956. * CHANGES
  957. *
  958. *   7/24/95 Eduard Schwan  - Changed "if" condition to use EPSILON, not equality
  959. *  12/12/95 Steve Demlow   - Clipped abs(up[Z]) to 1 to avoid acos overflow
  960. *
  961. ******************************************************************************/
  962.  
  963. void Compute_Coordinate_Transform(trans, origin, up, radius, length)
  964. TRANSFORM *trans;
  965. VECTOR origin;
  966. VECTOR up;
  967. DBL radius;
  968. DBL length;
  969. {
  970.   TRANSFORM trans2;
  971.   VECTOR tmpv;
  972.  
  973.   Make_Vector(tmpv, radius, radius, length);
  974.  
  975.   Compute_Scaling_Transform(trans, tmpv);
  976.  
  977.   if (fabs(up[Z]) > 1.0 - EPSILON)
  978.   {
  979.     Make_Vector(tmpv, 1.0, 0.0, 0.0)
  980.     up[Z] = up[Z] < 0.0 ? -1.0 : 1.0;
  981.   }
  982.   else
  983.   {
  984.     Make_Vector(tmpv, -up[Y], up[X], 0.0)
  985.   }
  986.  
  987.   Compute_Axis_Rotation_Transform(&trans2, tmpv, acos(up[Z]));
  988.  
  989.   Compose_Transforms(trans, &trans2);
  990.  
  991.   Compute_Translation_Transform(&trans2, origin);
  992.  
  993.   Compose_Transforms(trans, &trans2);
  994. }
  995.  
  996.  
  997.  
  998. /*****************************************************************************
  999. *
  1000. * FUNCTION
  1001. *
  1002. * INPUT
  1003. *   
  1004. * OUTPUT
  1005. *   
  1006. * RETURNS
  1007. *
  1008. * AUTHOR
  1009. *
  1010. *   POV-Ray Team
  1011. *   
  1012. * DESCRIPTION
  1013. *
  1014. *   -
  1015. *
  1016. * CHANGES
  1017. *
  1018. *   -
  1019. *
  1020. ******************************************************************************/
  1021.  
  1022. TRANSFORM *Create_Transform()
  1023. {
  1024.   TRANSFORM *New;
  1025.  
  1026.   New = (TRANSFORM *)POV_MALLOC(sizeof (TRANSFORM), "transform");
  1027.  
  1028.   MIdentity (New->matrix);
  1029.   MIdentity (New->inverse);
  1030.  
  1031.   return (New);
  1032. }
  1033.  
  1034.  
  1035.  
  1036. /*****************************************************************************
  1037. *
  1038. * FUNCTION
  1039. *
  1040. * INPUT
  1041. *   
  1042. * OUTPUT
  1043. *   
  1044. * RETURNS
  1045. *   
  1046. * AUTHOR
  1047. *
  1048. *   POV-Ray Team
  1049. *   
  1050. * DESCRIPTION
  1051. *
  1052. *   -
  1053. *
  1054. * CHANGES
  1055. *
  1056. *   -
  1057. *
  1058. ******************************************************************************/
  1059.  
  1060. TRANSFORM *Copy_Transform (Old)
  1061. TRANSFORM *Old;
  1062. {
  1063.   TRANSFORM *New;
  1064.   if (Old != NULL)
  1065.   {
  1066.     New  = Create_Transform ();
  1067.     *New = *Old;
  1068.   }
  1069.   else
  1070.   {
  1071.     New = NULL;
  1072.   }
  1073.  
  1074.   return (New);
  1075. }
  1076.  
  1077.  
  1078.  
  1079. /*****************************************************************************
  1080. *
  1081. * FUNCTION
  1082. *
  1083. * INPUT
  1084. *   
  1085. * OUTPUT
  1086. *   
  1087. * RETURNS
  1088. *   
  1089. * AUTHOR
  1090. *
  1091. *   POV-Ray Team
  1092. *   
  1093. * DESCRIPTION
  1094. *
  1095. *   -
  1096. *
  1097. * CHANGES
  1098. *
  1099. *   -
  1100. *
  1101. ******************************************************************************/
  1102.  
  1103. VECTOR *Create_Vector ()
  1104. {
  1105.   VECTOR *New;
  1106.  
  1107.   New = (VECTOR *)POV_MALLOC(sizeof (VECTOR), "vector");
  1108.  
  1109.   Make_Vector (*New, 0.0, 0.0, 0.0);
  1110.  
  1111.   return (New);
  1112. }
  1113.  
  1114.  
  1115.  
  1116. /*****************************************************************************
  1117. *
  1118. * FUNCTION
  1119. *
  1120. * INPUT
  1121. *   
  1122. * OUTPUT
  1123. *   
  1124. * RETURNS
  1125. *   
  1126. * AUTHOR
  1127. *
  1128. *   POV-Ray Team
  1129. *   
  1130. * DESCRIPTION
  1131. *
  1132. *   -
  1133. *
  1134. * CHANGES
  1135. *
  1136. *   -
  1137. *
  1138. ******************************************************************************/
  1139.  
  1140. DBL *Create_Float ()
  1141. {
  1142.   DBL *New_Float;
  1143.  
  1144.   New_Float = (DBL *)POV_MALLOC(sizeof (DBL), "float");
  1145.  
  1146.   *New_Float = 0.0;
  1147.  
  1148.   return (New_Float);
  1149. }
  1150.  
  1151.  
  1152.  
  1153. /*****************************************************************************
  1154. *
  1155. * FUNCTION
  1156. *
  1157. *   MInvers
  1158. *
  1159. * INPUT
  1160. *
  1161. *   m - matrix to invert
  1162. *   r - inverted matrix
  1163. *   
  1164. * OUTPUT
  1165. *
  1166. *   r
  1167. *   
  1168. * RETURNS
  1169. *   
  1170. * AUTHOR
  1171. *
  1172. *   Dieter Bayer
  1173. *   
  1174. * DESCRIPTION
  1175. *
  1176. *   Invert a 4x4 matrix.
  1177. *
  1178. * CHANGES
  1179. *
  1180. *   May 1994 : Creation.
  1181. *
  1182. ******************************************************************************/
  1183.  
  1184. void MInvers(r, m)
  1185. MATRIX r, m;
  1186. {
  1187.   DBL d00, d01, d02, d03;
  1188.   DBL d10, d11, d12, d13;
  1189.   DBL d20, d21, d22, d23;
  1190.   DBL d30, d31, d32, d33;
  1191.   DBL m00, m01, m02, m03;
  1192.   DBL m10, m11, m12, m13;
  1193.   DBL m20, m21, m22, m23;
  1194.   DBL m30, m31, m32, m33;
  1195.   DBL D;
  1196.   DBL rdiv;
  1197.  
  1198.   m00 = m[0][0];  m01 = m[0][1];  m02 = m[0][2];  m03 = m[0][3];
  1199.   m10 = m[1][0];  m11 = m[1][1];  m12 = m[1][2];  m13 = m[1][3];
  1200.   m20 = m[2][0];  m21 = m[2][1];  m22 = m[2][2];  m23 = m[2][3];
  1201.   m30 = m[3][0];  m31 = m[3][1];  m32 = m[3][2];  m33 = m[3][3];
  1202.  
  1203.   d00 = m11*m22*m33 + m12*m23*m31 + m13*m21*m32 - m31*m22*m13 - m32*m23*m11 - m33*m21*m12;
  1204.   d01 = m10*m22*m33 + m12*m23*m30 + m13*m20*m32 - m30*m22*m13 - m32*m23*m10 - m33*m20*m12;
  1205.   d02 = m10*m21*m33 + m11*m23*m30 + m13*m20*m31 - m30*m21*m13 - m31*m23*m10 - m33*m20*m11;
  1206.   d03 = m10*m21*m32 + m11*m22*m30 + m12*m20*m31 - m30*m21*m12 - m31*m22*m10 - m32*m20*m11;
  1207.  
  1208.   d10 = m01*m22*m33 + m02*m23*m31 + m03*m21*m32 - m31*m22*m03 - m32*m23*m01 - m33*m21*m02;
  1209.   d11 = m00*m22*m33 + m02*m23*m30 + m03*m20*m32 - m30*m22*m03 - m32*m23*m00 - m33*m20*m02;
  1210.   d12 = m00*m21*m33 + m01*m23*m30 + m03*m20*m31 - m30*m21*m03 - m31*m23*m00 - m33*m20*m01;
  1211.   d13 = m00*m21*m32 + m01*m22*m30 + m02*m20*m31 - m30*m21*m02 - m31*m22*m00 - m32*m20*m01;
  1212.  
  1213.   d20 = m01*m12*m33 + m02*m13*m31 + m03*m11*m32 - m31*m12*m03 - m32*m13*m01 - m33*m11*m02;
  1214.   d21 = m00*m12*m33 + m02*m13*m30 + m03*m10*m32 - m30*m12*m03 - m32*m13*m00 - m33*m10*m02;
  1215.   d22 = m00*m11*m33 + m01*m13*m30 + m03*m10*m31 - m30*m11*m03 - m31*m13*m00 - m33*m10*m01;
  1216.   d23 = m00*m11*m32 + m01*m12*m30 + m02*m10*m31 - m30*m11*m02 - m31*m12*m00 - m32*m10*m01;
  1217.  
  1218.   d30 = m01*m12*m23 + m02*m13*m21 + m03*m11*m22 - m21*m12*m03 - m22*m13*m01 - m23*m11*m02;
  1219.   d31 = m00*m12*m23 + m02*m13*m20 + m03*m10*m22 - m20*m12*m03 - m22*m13*m00 - m23*m10*m02;
  1220.   d32 = m00*m11*m23 + m01*m13*m20 + m03*m10*m21 - m20*m11*m03 - m21*m13*m00 - m23*m10*m01;
  1221.   d33 = m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m21*m12*m00 - m22*m10*m01;
  1222.  
  1223.   D = m00*d00 - m01*d01 + m02*d02 - m03*d03;
  1224.  
  1225.   if (D == 0.0)
  1226.   {
  1227.     Error("Singular matrix in MInvers.\n");
  1228.   }
  1229.   rdiv = (1.0 / D);
  1230.   r[0][0] =  d00*rdiv; r[0][1] = -d10*rdiv;  r[0][2] =  d20*rdiv; r[0][3] = -d30*rdiv;
  1231.   r[1][0] = -d01*rdiv; r[1][1] =  d11*rdiv;  r[1][2] = -d21*rdiv; r[1][3] =  d31*rdiv;
  1232.   r[2][0] =  d02*rdiv; r[2][1] = -d12*rdiv;  r[2][2] =  d22*rdiv; r[2][3] = -d32*rdiv;
  1233.   r[3][0] = -d03*rdiv; r[3][1] =  d13*rdiv;  r[3][2] = -d23*rdiv; r[3][3] =  d33*rdiv;
  1234. /*
  1235.   r[0][0] =  d00/D; r[0][1] = -d10/D;  r[0][2] =  d20/D; r[0][3] = -d30/D;
  1236.   r[1][0] = -d01/D; r[1][1] =  d11/D;  r[1][2] = -d21/D; r[1][3] =  d31/D;
  1237.   r[2][0] =  d02/D; r[2][1] = -d12/D;  r[2][2] =  d22/D; r[2][3] = -d32/D;
  1238.   r[3][0] = -d03/D; r[3][1] =  d13/D;  r[3][2] = -d23/D; r[3][3] =  d33/D;
  1239. */
  1240. }
  1241.  
  1242.  
  1243.  
  1244.